package com.tools.controller;

import cn.hutool.core.io.IoUtil;
import com.tools.common.beans.constant.Constants;
import com.tools.common.beans.constant.ControllerConstant;
import com.tools.common.beans.vo.Result;
import com.tools.modules.table.component.GenFileContext;
import com.tools.generator.entity.vo.PreviewVo;
import com.tools.modules.table.service.GenFileService;
import com.tools.generator.service.GeneratorService;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.io.*;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipOutputStream;

/**
 * @author 青青
 */
@RestController
@RequestMapping(ControllerConstant.API_GENERATOR_PREFIX)
public class GeneratorController extends BaseController {

    /**
     * 基础路径
     */
    private final String prefix = "generate/";

    @Autowired
    private GeneratorService generatorService;

    @Autowired
    private GenFileContext genFileContext;

    @GetMapping(value = {"/{page}.html"})
    public ModelAndView allPage(@PathVariable("page") String page) {
        return jumpPage(prefix + page);
    }

    /**
     * 预览代码
     */
    @GetMapping("/preview")
    public ModelAndView preview(@RequestParam Long tableId) throws Exception {
        List<PreviewVo> results = generatorService.preview(tableId);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("preview", results);
        modelAndView.setViewName(prefix + "preview-code");
        return modelAndView;
    }
    /**
     * 生成代码（自定义目录）
     */
    @PostMapping("code")
    public Result<String> code(@Valid @Size(min = 1,message = "至少选择一条数据") @RequestParam("tableIds[]") Long[] tableIds){
        for (Long tableId : tableIds) {
            generatorService.generatorCode(tableId);
        }
        return Result.OK();
    }

    /**
     * 生成代码
     */
    @RequestMapping("/download")
    public void download(@NotBlank(message = "至少选择一张表") @RequestParam("tables") String tables, HttpServletResponse response) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        String[] tableArr = tables.split(Constants.SYMBOL.COMMA);
        for (String tableId : tableArr) {
            generatorService.downloadCode(Long.parseLong(tableId), zip);
        }
        IoUtil.close(zip);
        byte[] data = outputStream.toByteArray();
        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=\"tool-code.zip\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        IoUtil.write(response.getOutputStream(), false, data);
    }

    /**
     * 生成html格式-->拷贝到临时目录-->响应给前端-->删除临时文件
     *
     * @param response 响应对象
     */
    @PostMapping("/genFile")
    public void genFile(@Valid @NotBlank(message = "请选择类型") @RequestParam("type") String type,
                        @Size(min = 1,message = "至少选择一条数据") @RequestParam("tableIds[]") Long[] tableIds,
                        HttpServletResponse response) throws Exception {

        GenFileService genFileService = genFileContext.select(type);
        File file = genFileService.genFile(Arrays.asList(tableIds));
        FileInputStream fileInputStream = FileUtils.openInputStream(file);
        ServletOutputStream outputStream = response.getOutputStream();
        IOUtils.copy(fileInputStream, outputStream);

        // 关闭流
        IOUtils.closeQuietly(fileInputStream);
        IOUtils.closeQuietly(outputStream);

        // 删除文件
        FileUtils.deleteQuietly(file);
    }

    /**
     * 下载文件并删除
     *
     * @param file     file对象
     * @param response HttpServletResponse
     */
    public void downDel(File file, String contentType, HttpServletResponse response) throws IOException {
        // 设置响应信息
        response.setHeader("Content-type", contentType);
        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName=" + file.getName());
        ServletOutputStream outputStream = response.getOutputStream();

        // 获取文件
        FileInputStream fileInputStream = FileUtils.openInputStream(file);
        IOUtils.copy(fileInputStream, outputStream);

        // 关闭流
        IOUtils.closeQuietly(fileInputStream);
        IOUtils.closeQuietly(outputStream);

        // 删除文件
        FileUtils.deleteQuietly(file);
    }
}
